package cn.buk.tms.flight.service;

import cn.buk.api.szkj.dto.eterm.PnrInfo;
import cn.buk.api.szkj.dto.eterm.PnrInfoPassenger;
import cn.buk.api.szkj.dto.eterm.PnrInfoTicket;
import cn.buk.api.szkj.dto.eterm.response.EtdzResponse;
import cn.buk.common.JsonResult;
import cn.buk.qms.service.BaseFlightOrderService;
import cn.buk.tms.entity.misc.EntDepartment;
import cn.buk.tms.entity.order.flight.FlightOrder;
import cn.buk.tms.entity.order.flight.FlightOrderPassenger;
import cn.buk.tms.flight.request.FlightOrderRequestDto;
import cn.buk.tms.flight.util.FlightOrderUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import static cn.buk.tms.common.constant.TmsOrderConstant.AUTO_PRINT_TICKET_NONE;

/**
 * 用 szkj 提供的eterm接口进行BSP自动开票
 * @author yfdai
 */
@Service
public class AutoTicketBspSzkjWorker extends BaseFlightOrderService implements AutoTicketStrategy  {

  private final EtermService etermService;

  @Autowired
  public AutoTicketBspSzkjWorker(EtermService etermService) {
    this.etermService = etermService;
  }

  @Override
  public void autoTicketFlightOrder(int enterpriseId, String username, int orderId) {
    FlightOrder orderInfo = flightOrderDao.getOrderDetailById(orderId);
    assert enterpriseId == orderInfo.getEnterpriseId();

    JsonResult jsonResult0 = FlightOrderUtil.validateOrderInfoByAutoTicketing(orderInfo);
    if (!JsonResult.STATUS_OK.equalsIgnoreCase(jsonResult0.getStatus())) {
      return;
    }

    final String key = String.format("etdz_pnr_%d_%s", orderInfo.getEnterpriseId(), orderInfo.getOrderNo());
    //控制频率，5分钟只尝试三次出票
    if (redisDao.incrApiCallCount(key, 60L * 5, 3) == 0) {
      return;
    }

    PnrInfo pnrInfo = null;
    EtdzResponse response = etermService.etdz(enterpriseId, username, orderInfo);
    if (response.getCode() != 1) {
      int retcode = processEtdzErrorMessages(enterpriseId, username, orderInfo, response);
      if (retcode == 0) {
        return;
      } else {
        //获取编码详情
        var rs = etermService.rt(enterpriseId, username, orderInfo.getPnrNo());
        if (rs.getCode() == 1 && "1".equalsIgnoreCase(rs.getPnrInfo().getIsEt())) {
          pnrInfo = rs.getPnrInfo();
        }
      }
    } else {
      pnrInfo = response.getPnrInfo();
    }

    if (pnrInfo == null) {
      return;
    }

    //直接用返回的结果回填票号和佣金
    //DONE 回填票号
    processEtdzTickets(enterpriseId, username, orderInfo, pnrInfo);

    // 回填佣金
    if (processEtdzCommission(enterpriseId, username, pnrInfo, orderInfo) == 1) {
      // 完成订单
      doFinishFlightOrder(enterpriseId, username, orderId);
    }
  }


  /**
   * 处理ETDZ接口返回的错误信息
   * 返回：0 - 停止执行下一步
   *      1 - 可以继续下一步
   */
  private int processEtdzErrorMessages(final int enterpriseId, final String username, final FlightOrder orderInfo,
                                        final EtdzResponse response) {
    String content = "订单(" + orderInfo.getOrderNo() + ", " + orderInfo.getPnrNo() + ")使用接口出票返回"
            + response.getCode() + " : " + response.getMsg();
    doSendAlert(enterpriseId, content, null, EntDepartment.DEPT_TICKETING);

    if (response.getMsg().contains("该编码已经被取消")
            || response.getMsg().contains("不是预订状态")
            || response.getMsg().contains("该编码状态为[NO]")
    ) {
      //接口返回错误
      content += ", 停止自动出票.";
      flightOrderDao.updateFlightOrderAutoTicketing(enterpriseId, username, orderInfo.getId(),
              AUTO_PRINT_TICKET_NONE, content);
      return 0;
    } else {
      //接口返回错误
      flightOrderDao.appendFlightOrderLog(enterpriseId, username, orderInfo.getId(), content);
      return 1;
    }
  }



  private void processEtdzTickets(final int enterpriseId, final String username, final FlightOrder orderInfo,
                                  final PnrInfo pnrInfo) {
    for (PnrInfoPassenger psgInfo0 : pnrInfo.getPassengers()) {
      for (FlightOrderPassenger psgInfo1 : orderInfo.getPassengers()) {
        if (psgInfo1.getName().equalsIgnoreCase(psgInfo0.getName())) {
          psgInfo1.setTicketNo(psgInfo0.getTicketNo());
        }
      }
    }

    execUpdateTicketNo(enterpriseId, username, orderInfo, 1);
  }


  private int processEtdzCommission(final int enterpriseId, final String username, final PnrInfo pnrInfo,
                                    final FlightOrder orderInfo) {
    if (pnrInfo.getTickets() == null || pnrInfo.getTickets().isEmpty()) {
      return 0;
    }

    //获取到了佣金，计算机票订单的成本
    FlightOrderRequestDto dto = FlightOrderUtil.createDtoByFlightOrder(orderInfo);

    //校验价格和税收是否相等
    final int price0 = (int) dto.getAdultPrice().getPrice();
    final int tax0 = (int) dto.getAdultPrice().getTax();
    for (PnrInfoTicket ticket : pnrInfo.getTickets()) {
      final int price1 = (int) (ticket.getPrice() == null ? 0 : ticket.getPrice());
      final int tax1 = (int) (ticket.getTax() == null ? 0 : ticket.getTax());
      if (price0 != price1 || tax0 != tax1) {
        //记录日志
        final String content = ticket.getTicketNo() + ": " + price0 + " ?= " + price1 + ", " + tax0 + " ?= " + tax1;
        flightOrderDao.appendFlightOrderLog(enterpriseId, username, orderInfo.getId(), content);
        doSendAlert(enterpriseId, content, null, EntDepartment.DEPT_ADMINISTRATOR);
        return 0;
      }

      dto.getAdultPrice().setCommission(ticket.getCommission() * 1.0);
    }

    return flightOrderDao.updatePrice(enterpriseId, username, orderInfo.getId(), dto);
  }

}
